package org.ezplatform.goa.goods.service;

import java.util.*;

import org.apache.commons.collections.CollectionUtils;
import org.ezplatform.cloud.api.component.attachment.AttachmentUtilsService;
import org.ezplatform.cloud.api.component.popuser.PopUserScopeUtilService;
import org.ezplatform.cloud.api.system.org.OrgApiService;
import org.ezplatform.cloud.api.system.user.UserApiService;
import org.ezplatform.component.permission.service.CmpApplyScopeService;
import org.ezplatform.component.permission.service.CmpPermissionService;
import org.ezplatform.component.permission.utils.CmpPermissionConstant;
import org.ezplatform.core.common.WebUser;
import org.ezplatform.core.dao.jpa.JpaBaseDao;
import org.ezplatform.core.pagination.PropertyFilter;
import org.ezplatform.core.service.BaseService;
import org.ezplatform.core.web.util.WebUtils;
import org.ezplatform.goa.goods.constant.RightConstant;
import org.ezplatform.goa.goods.dao.GoaGoodsReceiveDao;
import org.ezplatform.goa.goods.entity.GoaGoodsAllotmentSub;
import org.ezplatform.goa.goods.entity.GoaGoodsReceive;
import org.ezplatform.util.GlobalConstant;
import org.ezplatform.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.sql.Timestamp;
import javax.servlet.http.HttpServletRequest;
@Service
@Transactional
public class GoaGoodsReceiveService extends BaseService<GoaGoodsReceive, String> {
    private final Logger logger = LoggerFactory.getLogger(GoaGoodsReceiveService.class);


    @Autowired
    private UserApiService userApiService;

    @Autowired
    private OrgApiService orgApiService;

    @Autowired
    private CmpPermissionService cmpPermissionService;

    @Autowired
    private CmpApplyScopeService cmpApplyScopeService;

    @Autowired
    private PopUserScopeUtilService popUserScopeUtilService;

    @Autowired
    private AttachmentUtilsService attachmentUtilsService;

    @Autowired
    private GoaGoodsReceiveDao itemDao;

    @Override
    protected JpaBaseDao<GoaGoodsReceive, String> getEntityDao() {
        return this.itemDao;
    }


    /**
     * 更新领用表信息
     *
     * @author wandz
     */
    public void updateReceiveInfo(String goodsId, String receiveUserId, Integer receiveNumber) {
        itemDao.updateReceiveInfo(goodsId, receiveUserId, receiveNumber);
    }


    /**
	 * 处理领用表已领用量、当前量
	 * @author wandz
	 * @param aEntity
	 * @return
	 */
	public GoaGoodsReceive dealReceiveInfo(GoaGoodsAllotmentSub subEntity) {
		String goodsId = subEntity.getGoodsId();
		String receiveUserId = subEntity.getReceiveUserId();
		Integer allotmentNumber = subEntity.getAllotmentNumber();//实际配发数量
		GoaGoodsReceive sEntity = new GoaGoodsReceive();
		Integer curNumber = allotmentNumber;//当前数量
		List<GoaGoodsReceive> receiveList = itemDao.getReceiveInfoList(goodsId, receiveUserId);
		if(receiveList!=null&&receiveList.size()>0) {
			sEntity = receiveList.get(0);
			Integer tempReceiveNumber = sEntity.getReceiveNumber();
			if(null!=tempReceiveNumber) {
				allotmentNumber = tempReceiveNumber + allotmentNumber; 
			}
			Integer tempCurNumber = sEntity.getCurrentNumber();
			if(null!=tempCurNumber) {
				curNumber = tempCurNumber + curNumber; 
			}
		}else {
			//新增赋值
			sEntity.setReceiveUserId(subEntity.getReceiveUserId());
			sEntity.setGoodsId(subEntity.getGoodsId());
			sEntity.setGoodsCode(subEntity.getGoodsCode());
			sEntity.setGoodsName(subEntity.getGoodsName());
			sEntity.setGoodsClassify(subEntity.getGoodsClassify());
			sEntity.setGoodsBrand(subEntity.getGoodsBrand());
			sEntity.setGoodsSpecification(subEntity.getGoodsSpecification());
			sEntity.setMeasurementUnit(subEntity.getMeasurementUnit());
			sEntity.setIsDelete(0);
		}
        //存仓库值
        sEntity.setBelongingWarehouse(subEntity.getBelongingWarehouse());
        sEntity.setReceiveTime(new Date());
		sEntity.setReceiveNumber(allotmentNumber);
		sEntity.setCurrentNumber(curNumber);
		return sEntity;
	}


    /**
     * 物品领用列表数据显示
     * @param propertyFilters
     * @param pageable
     * @param searchParam
     * @return
     */
    public Page<Map> getGoodsReceiveList(List<PropertyFilter> propertyFilters, Pageable pageable,
                                         Map<String, String> searchParam) {
        WebUser user = WebUtils.getCurrentUser();

        StringBuffer sql = new StringBuffer();
        Map<String, Object> paramMap = new HashMap<>();

        sql.append(" select t.id,t.goodsId,t.warehouseName,t.unusedNumber,t.isShowprice, ");
        sql.append(" t.goodsName,t.classifyName,t.measurementUnit,t.unitPrice,t.attachment, ");
        sql.append(" t.synum ");
        sql.append(" from ( ");
        sql.append(" select a.id,a.goods_id goodsId,c.warehouse_name warehouseName,a.unused_number unusedNumber, ");
        sql.append(" b.goods_name goodsName,d.classify_name classifyName,b.measurement_unit measurementUnit, ");
        sql.append(" b.unit_price unitPrice,b.is_showprice isShowprice,b.attachment,b.corp_id, ");
        sql.append(" c.suit_scope,a.createdBy,a.createdOrg, ");
        sql.append(" d.classify_idsstr cIdsstr,d.sort_no cSortNo,d.createdDate cCreatedDate,b.sort_no iSortNo, ");
        sql.append(" b.createdDate iCreatedDate,c.sort_no wSortNo,c.createdDate wCreatedDate ");
        sql.append(",p.synum ");
        sql.append(" from goa_goods_stock a ");
        sql.append(" left join goa_goods_info b on a.goods_id = b.id ");
        sql.append(" inner join goa_goods_warehouse c on c.id = a.warehouse_id ");
        sql.append(" inner join goa_goods_classify d on d.id = b.goods_classify_id ");
        sql.append(" left join ( select goods_id as pid ,sum(change_number) as synum from goa_goods_stock_change where stock_status ='2' group by goods_id) as p on  p.pid =b.id ");
        sql.append(" where a.is_delete = 0 and b.is_delete = 0 and c.is_delete=0  ");
        sql.append(" ) t ");
        sql.append(" where 1=1 ");
        //查询条件
        if (null != searchParam && searchParam.size() > 0) {
            //物品名称
            String goodsName = searchParam.get("goodsName");
//            if (StringUtils.isNotEmpty(goodsName)) {
//                // 处理特殊字符 _
//                sql.append(" and t.goodsName like :goodsName ");
//                   paramMap.put("goodsName", "%" + goodsName + "%");
//            }
            if (StringUtils.isNotEmpty(goodsName)) {
                String condition;
                String paramName = "goodsName";
                // 处理特殊字符 _
                String escapedGoodsName = goodsName.replace("_", "\\_"); // MySQL 默认使用 \ 转义
                if (GlobalConstant.isOracle()) {
                    escapedGoodsName = goodsName.replace("_", "!_");
                    escapedGoodsName = escapedGoodsName.replace("\\", "");
                    condition = " AND t.\"GOODSNAME\" LIKE :" + paramName + " ESCAPE '!'";
                    paramMap.put(paramName, "%" + escapedGoodsName + "%");
                    sql.append(condition);
                } else { // mysql
                    sql.append(" and t.goodsName like :goodsName ");
                    paramMap.put("goodsName", "%" + goodsName + "%");
                }
            }
            String classifyName = searchParam.get("classifyName");
            if (StringUtils.isNotEmpty(classifyName)) {
                sql.append(" and t.classifyName like :classifyName ");
                paramMap.put("classifyName", "%" + classifyName + "%");
            }
        }

        String scopeSql = this.cmpApplyScopeService.getInScopeDataSql(user.getUserId(), "goa_goods_warehouse_scope",
                "goa_goods_warehouse", "suit_scope", "t", paramMap);
        sql.append(" and ( " + scopeSql + " ) ");

        // 排序
        String finalSQL = PropertyFilter.getSqlByFilterAndPageable("t", sql.toString(), "",
                propertyFilters, pageable);

        if (finalSQL.contains("order by")) {// 排序处理
            int i = finalSQL.split("order by").length;
            if (i > 0) {
                if (i == 1) {
                    finalSQL = finalSQL.split("order by")[0] +
                            " order by t.cIdsstr asc,t.cSortNo asc,t.cCreatedDate desc,t.iSortNo asc,t.iCreatedDate desc,t.wSortNo asc,t.wCreatedDate desc ";
                } else {
                    finalSQL = finalSQL.split("order by")[0] + "order by " + finalSQL.split("order by")[1];
                }
            }
        } else {
            //finalSQL += " order by t.cIdsstr asc,t.cSortNo asc,t.cCreatedDate desc,t.iSortNo asc,t.iCreatedDate desc ";
            finalSQL += " order by  t.cIdsstr asc,t.cSortNo asc,t.cCreatedDate desc,t.iSortNo asc,t.iCreatedDate desc ";
        }
        //分页查询
        Page<Map> page = this.findByPageNativeSQL(pageable, finalSQL, paramMap);
        //数据权限控制
        Map<String, String> permissionInfoMap = new HashMap<>();

        //处理page中的数据
        List<Map> list = page.getContent();
        if (CollectionUtils.isNotEmpty(list)) {
            for (Map map : list) {
                String attachment = StringUtils.null2String(map.get("attachment"));
                if (StringUtils.isNotEmpty(attachment)) {
                    String attachmentJson = this.attachmentUtilsService.getAttachmentInfo(attachment, this.getToken());
                    if (StringUtils.isNotEmpty(attachmentJson)) {
                        map.put("attachmentJson", attachmentJson);
                    }
                }
            }
        }

        list = this.cmpPermissionService.processBusinessListByDataScope(list, user, permissionInfoMap);
        return new PageImpl<>(list, pageable, page.getTotalElements());
    }

    /**
     * 对 LIKE 查询参数进行转义，确保 _ 和 % 不被当作通配符
     */
    public static String escapeForLikeClause(String input) {
        if (input == null) return null;
        return input
                .replace("\\", "\\\\")     // 把 \ 替换成 \\
                .replace("%", "\\%")       // 把 % 替换成 \%
                .replace("_", "\\_");       // 把 _ 替换成 \_
    }

    public List<Map> initGoosType(Map<String, String> searchParam) {
        WebUser user = WebUtils.getCurrentUser();

        StringBuffer sql = new StringBuffer();
        Map<String, Object> paramMap = new HashMap<>();

        sql.append(" select t.id,t.goodsId,t.warehouseName,t.unusedNumber,t.isShowprice, ");
        sql.append(" t.goodsName,t.classifyName,t.measurementUnit,t.unitPrice,t.attachment ");
        sql.append(" from ( ");
        sql.append(" select a.id,a.goods_id goodsId,c.warehouse_name warehouseName,a.unused_number unusedNumber, ");
        sql.append(" b.goods_name goodsName,d.classify_name classifyName,b.measurement_unit measurementUnit, ");
        sql.append(" b.unit_price unitPrice,b.is_showprice isShowprice,b.attachment,b.corp_id, ");
        sql.append(" c.suit_scope,a.createdBy,a.createdOrg, ");
        sql.append(" d.classify_idsstr cIdsstr,d.sort_no cSortNo,d.createdDate cCreatedDate,b.sort_no iSortNo, ");
        sql.append(" b.createdDate iCreatedDate,c.sort_no wSortNo,c.createdDate wCreatedDate ");
        sql.append(" from goa_goods_stock a ");
        sql.append(" left join goa_goods_info b on a.goods_id = b.id ");
        sql.append(" inner join goa_goods_warehouse c on c.id = a.warehouse_id ");
        sql.append(" inner join goa_goods_classify d on d.id = b.goods_classify_id ");
        sql.append(" where a.is_delete = 0 and b.is_delete = 0 and c.is_delete=0  ");
        sql.append(" ) t ");
        sql.append(" where 1=1 ");



        String scopeSql = this.cmpApplyScopeService.getInScopeDataSql(user.getUserId(), "goa_goods_warehouse_scope",
                "goa_goods_warehouse", "suit_scope", "t", paramMap);
        sql.append(" and ( " + scopeSql + " ) ");
        sql.append(" order by t.cIdsstr asc,t.cSortNo asc,t.cCreatedDate desc,t.iSortNo asc,t.iCreatedDate desc ");


        List<Map> viewSendFileList=this.findByListNativeQuery(sql.toString(), "", paramMap);
        return viewSendFileList;

    }

    public Page goodsUserList(Map<String,String> map, HttpServletRequest request){
        Pageable pageable = PropertyFilter.buildPageableFromHttpRequest(request);
        StringBuffer sql = new StringBuffer();
        Map<String, Object> paramMap = new HashMap<String, Object>();
        sql.append(" select bb.id,aa.allotment_code,bb.goods_id,bb.goods_code,bb.goods_name,bb.goods_classify,bb.allotment_number ");
        sql.append(" ,bb.receive_user,bb.receive_department,aa.apply_user,aa.apply_time,aa.status,aa.createddate,aa.formid ");
        sql.append(" from goa_goods_allotment  aa  left join goa_goods_allotment_sub bb on aa.id= bb.fkid ");
        sql.append(" where 1=1 and aa.status>0 ");
        if (null != map && map.size() > 0) {
            String goodsid = map.get("goodsid");
            sql.append(" and bb.goods_id = :goodsid ");
            paramMap.put("goodsid",goodsid);
        }
        sql.append(" order by apply_time desc ");
        Page<Map> page = super.findByPageNativeSQL(pageable, String.valueOf(sql), paramMap);
        List<Map> list = page.getContent();
        return new PageImpl(list, pageable, page.getTotalElements());
    }


    public List<Map> getUserFGCS(){
        Map<String, Object> paramMap = new HashMap<>();
        WebUser user = WebUtils.getCurrentUser();
        StringBuffer sql = new StringBuffer();
        sql.append(" select t.id,b.fielddatavalue,b.fielddata ,c.id as cid ,d.id as did ");
        sql.append(" from sys_user t  ");
        sql.append(" left join sys_org_scope b on t.id = b.scopevalue ");
        sql.append(" left join sys_org c on c.user_leaders = b.fielddatavalue ");
        sql.append(" left join sys_org d on d.deputy_leaders = b.fielddatavalue ");
        sql.append(" where 1=1 and  fielddatavalue is not null  ");
        sql.append(" and t.id = '").append(user.getUserId()).append("'");
        List<Map> viewSendFileList = this.findByListNativeQuery(sql.toString(), "", paramMap);
        return viewSendFileList;
    }

    public List<Map> getLqGoodsByUser(Map<String,String> map){
        Map<String, Object> paramMap = new HashMap<>();
        WebUser user = WebUtils.getCurrentUser();
        StringBuffer sql = new StringBuffer();
        sql.append(" select yy.goods_name,sum(allotment_number) as total from ( ");
        sql.append(" select  bb.id,aa.allotment_code,bb.goods_id,bb.goods_code,bb.goods_name,bb.goods_classify,bb.allotment_number  ");
        sql.append(" ,bb.receive_user,bb.receive_user_id,bb.receive_department,aa.apply_user,aa.apply_time,aa.status,aa.createddate,aa.formid ");
        sql.append(" from goa_goods_allotment  aa ");
        sql.append(" left join goa_goods_allotment_sub bb on aa.id= bb.fkid  ");
        sql.append(" where receive_user_id =:userid  ");
        if (null != map && map.size() > 0) {
            String start=map.get("start");;//登记时间
            String end =  map.get("end");;//登记时间
            if (StringUtils.isNotBlank(start)) {
                sql.append(" and aa.apply_time >= :start ");
                paramMap.put("start", Timestamp.valueOf(start + " 00:00:00"));
            }
            if (StringUtils.isNotBlank(end)) {
                sql.append(" and aa.apply_time <= :end ");
                paramMap.put("end", Timestamp.valueOf(end + " 23:59:59"));
            }
        }
        sql.append(" ) as yy ");
        sql.append(" group by yy.goods_name ");
        paramMap.put("userid",user.getUserId());
        List<Map> viewSendFileList = this.findByListNativeQuery(sql.toString(), "", paramMap);
        return viewSendFileList;
    }
    public List<Map> getLqGoodsByUserList(Map<String,String> map,List<String> useridlist){
        Map<String, Object> paramMap = new HashMap<>();
        WebUser user = WebUtils.getCurrentUser();
        StringBuffer sql = new StringBuffer();
        sql.append(" select yy.goods_name,sum(allotment_number) as total from ( ");
        sql.append(" select  bb.id,aa.allotment_code,bb.goods_id,bb.goods_code,bb.goods_name,bb.goods_classify,bb.allotment_number  ");
        sql.append(" ,bb.receive_user,bb.receive_user_id,bb.receive_department,aa.apply_user,aa.apply_time,aa.status,aa.createddate,aa.formid ");
        sql.append(" from goa_goods_allotment  aa ");
        sql.append(" left join goa_goods_allotment_sub bb on aa.id= bb.fkid  ");
        sql.append(" where receive_user_id in(:userid)  ");
        if (null != map && map.size() > 0) {
            String start=map.get("start");;//登记时间
            String end =  map.get("end");;//登记时间
            if (StringUtils.isNotBlank(start)) {
                sql.append(" and  apply_time >= :start ");
                paramMap.put("start", Timestamp.valueOf(start + " 00:00:00"));
            }
            if (StringUtils.isNotBlank(end)) {
                sql.append(" and apply_time <= :end ");
                paramMap.put("end", Timestamp.valueOf(end + " 23:59:59"));
            }
        }
        sql.append(" ) as yy ");
        sql.append(" group by yy.goods_name ");
        paramMap.put("userid",user.getUserId());
        List<Map> viewSendFileList = this.findByListNativeQuery(sql.toString(), "", paramMap);
        return viewSendFileList;
    }

    public List<Map> getOrgInUser(String[] leadrsplit){
        List<Map> list =  new ArrayList();
        for(int i =0;i<leadrsplit.length;i++){
            String orgid= leadrsplit[i];
            String  org_id_path = getorg_id_path(orgid);
            List<Map> user_org_list = getUserByOrgPathId(org_id_path);
            if(user_org_list.size()>0){
                list.addAll(user_org_list);
            }
        }
        return list;
    }

    public String getorg_id_path(String orgid){
        StringBuffer sql = new StringBuffer();
        sql.append(" select org_id_path  from sys_org where id =:orgid ");
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("orgid",orgid);
        List<Map> viewSendFileList = this.findByListNativeQuery(sql.toString(), "", paramMap);
        String res = "";
        if(viewSendFileList.size()>0){
            res = viewSendFileList.get(0).get("org_id_path").toString();
        }
        return  res;
    }
    public List<Map> getUserByOrgPathId(String org_id_path){
        StringBuffer sql = new StringBuffer();
        sql.append(" select * from sys_user where org_id in (select id from sys_org where org_id_path like '%");
        sql.append(org_id_path).append("%')");
        Map<String, Object> paramMap = new HashMap<>();
        //  paramMap.put("org_id_path",org_id_path);
        List<Map> viewSendFileList = this.findByListNativeQuery(sql.toString(), "", paramMap);
        return viewSendFileList;
    }

}

